package mymarshal

import (
	"fmt"
	"reflect"
	"strings"
)

//InvalidTypeException 是不正常类型异常,因为有些类型Marshal序列化以后得不到值
type InvalidTypeException string

func (v InvalidTypeException) Error() string {
	return ""
}

//StructtoString 是用来处理结构体转成字符串使用的
func StructtoString(v interface{}) string {
	result := ""

	typee := reflect.TypeOf(v)

	val := reflect.ValueOf(v)

	for i := 0; i < typee.NumField(); i++ {
		f := typee.Field(i)
		value := val.Field(i)
		if f.PkgPath == "" {
			othername := f.Tag.Get("json")
			key := f.Name
			if othername != "" {
				key = othername
			}
			key = `"` + key + `"`
			result += key + ":" + ValuetoString(value.Interface()) + ","
		}
	}
	return "{" + strings.TrimRight(result, ",") + "}"
}

//ValuetoString 是用来处理任意对象转为字符串使用的
func ValuetoString(v interface{}) string {
	str := ""

	vtype := reflect.TypeOf(v)
	typee := vtype.Kind()
	va := reflect.ValueOf(v)
	switch typee {
	case reflect.Ptr:
		return ValuetoString(va.Elem().Interface())
	case reflect.Bool, reflect.Int, reflect.Float64:
		str = fmt.Sprintf("%v", v)
	case reflect.String:
		str = fmt.Sprintf("%v", v)
		str = `"` + str + `"`
	case reflect.Map:
		keys := va.MapKeys()
		for _, key := range keys {

			value := va.MapIndex(key)
			str += ValuetoString(key.Interface()) + ":" + ValuetoString(value.Interface())
			str += ","
		}
		return "{" + strings.TrimRight(str, ",") + "}"
	case reflect.Slice:
		for i := 0; i < va.Len(); i++ {
			str += ValuetoString(va.Index(i).Interface())
			str += ","
		}
		return "[" + strings.TrimRight(str, ",") + "]"
	case reflect.Struct:
		return StructtoString(v)
	}
	return str
}

//JsonMarshal 是整个包的核心函数
func JsonMarshal(v interface{}) ([]byte, error) {
	result := ValuetoString(v)
	if result == "" {
		return nil, InvalidTypeException("")
	}
	return []byte(result), nil
}
